www.gusucode.com > 一个美化窗口实例 VC++漂亮界面源码程序 > 一个美化窗口实例 VC++漂亮界面/VC++菜单类的演示/VC++菜单类的演示/MyListCtrl.cpp
#include "stdafx.h" #include "MyListCtrl.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // download by http:www.codesc.net struct ItemData { public: ItemData() : arrpsz( NULL ), dwData( NULL ) {} LPTSTR* arrpsz; DWORD dwData; private: ItemData( const ItemData& ); ItemData& operator=( const ItemData& ); }; CMyListCtrl::CMyListCtrl() : m_iNumColumns( 0 ) , m_iSortColumn( -1 ) , m_bSortAscending( TRUE ) ,blnMenu(TRUE) ,itemX(-1) ,itemY(-1) ,blnAllEdit(TRUE) ,m_EditStyle(ctr_Edit_DblClick) { } CMyListCtrl::~CMyListCtrl() { CboArrayIndex.FreeExtra(); strArrayEditStyle.FreeExtra(); for(int i=0;i<CboArrayData.GetSize();i++) { CStringArray *strArray=(CStringArray *)CboArrayData.GetAt(i); strArray->FreeExtra(); } CboArrayData.FreeExtra(); NumArrayIndex.FreeExtra(); NumArrayData.FreeExtra(); } BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl) //{{AFX_MSG_MAP(CMyListCtrl) ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick) ON_WM_DESTROY() ON_WM_RBUTTONDOWN( ) ON_WM_LBUTTONDOWN( ) ON_WM_LBUTTONDBLCLK( ) ON_WM_PARENTNOTIFY() ON_WM_HSCROLL() ON_WM_VSCROLL() ON_COMMAND(ID_MENU_list, OnMenuitemlist) ON_COMMAND(ID_MENU_icon, OnMenuitemicon) ON_COMMAND(ID_MENU_smallicon, OnMenuitemsmallicon) ON_COMMAND(ID_MENU_report, OnMenuitemreport) ON_COMMAND(ID_MENU_No,OnMenuNo) ON_COMMAND(ID_MENU_Click,OnMenuClick) ON_COMMAND(ID_MENU_DblClick,OnMenuDblClick) //}}AFX_MSG_MAP END_MESSAGE_MAP() void CMyListCtrl::PreSubclassWindow() { ctl_EditText.Create(ES_AUTOHSCROLL|WS_CHILD|ES_LEFT|ES_WANTRETURN|WS_BORDER,CRect(0,0,0,0),this,ID_EditText); ctl_EditDateTime.Create(ES_AUTOHSCROLL|WS_CHILD|ES_CENTER|ES_WANTRETURN|WS_BORDER,CRect(0,0,0,0),this,ID_EditDateTime); ctl_EditComboDown.Create(WS_CHILD|CBS_DROPDOWN |WS_VSCROLL | WS_TABSTOP,CRect(0,0,0,0),this,ID_EditCboDown); ctl_EditComboDownList.Create(WS_CHILD|CBS_DROPDOWNLIST |WS_VSCROLL | WS_TABSTOP,CRect(0,0,0,0),this,ID_EditCboList); ctl_EditNum.Create(ES_AUTOHSCROLL|WS_CHILD|ES_LEFT|ES_WANTRETURN|WS_BORDER,CRect(0,0,0,0),this,ID_EditText); CFont *ft=GetFont(); ctl_EditComboDown.SetFont(ft,TRUE); ctl_EditText.SetFont(ft,TRUE); ctl_EditDateTime.SetFont(ft,TRUE); ctl_EditNum.SetFont(ft,TRUE); ctl_EditComboDownList.SetFont(ft,TRUE); ctl_EditComboDownList.SetExtendedUI(TRUE); ctl_EditComboDown.SetExtendedUI(TRUE); // ModifyStyle(0,LVS_OWNERDRAWFIXED); CListCtrl::PreSubclassWindow(); } //添加一项 int CMyListCtrl::AddItem(int image) { LPTSTR* arrpsz = new LPTSTR[ m_iNumColumns ]; for(int i=0;i<m_iNumColumns;i++) { arrpsz[ i ] = new TCHAR[1]; (void)lstrcpy( arrpsz[ i ], "" ); } int iIndex=InsertItem(GetItemCount(),"",image); VERIFY( SetTextArray( iIndex, arrpsz ) ); return iIndex; } //设置排列方式 void CMyListCtrl::SetMyStyle(DWORD dwNewStyle) { if(itemX>=0&& itemY>=0) SetEditPos(FALSE,itemX,itemY,FALSE); DWORD oldStyle; oldStyle=GetWindowLong(GetSafeHwnd(),GWL_STYLE); if((oldStyle&LVS_TYPEMASK)!=dwNewStyle) { oldStyle&=~LVS_TYPEMASK; oldStyle|=dwNewStyle; SetWindowLong(GetSafeHwnd(),GWL_STYLE,oldStyle); } } //返回排列方式 DWORD CMyListCtrl::GetMyStyle() { DWORD oldStyle,newStyle; oldStyle=GetWindowLong(GetSafeHwnd(),GWL_STYLE); newStyle=oldStyle&LVS_TYPEMASK; return newStyle; } void CMyListCtrl::OnMenuitemlist() { SetMyStyle(LVS_LIST); } void CMyListCtrl::OnMenuitemicon() { SetMyStyle(LVS_ICON); } void CMyListCtrl::OnMenuitemreport() { SetMyStyle(LVS_REPORT); } void CMyListCtrl::OnMenuitemsmallicon() { SetMyStyle(LVS_SMALLICON); } void CMyListCtrl::OnMenuClick () { m_EditStyle=ctr_Edit_Click; SetEditPos(FALSE,itemX,itemY,FALSE); } void CMyListCtrl::OnMenuDblClick() { m_EditStyle=ctr_Edit_DblClick; SetEditPos(FALSE,itemX,itemY,FALSE); } void CMyListCtrl::OnMenuNo() { if(m_EditStyle==ctr_Edit_No) return; m_EditStyle=ctr_Edit_No; if(!blnAllEdit) return; if(itemY<0) return; CString strText; switch(GetColumnStyle(itemY)) { case ctr_Edit_CboDownList: ctl_EditComboDownList.ShowDropDown(FALSE); ctl_EditComboDownList.GetWindowText(strText); SetItemText(itemX,itemY,strText); ctl_EditComboDownList.ShowWindow(SW_HIDE); break; case ctr_Edit_CboDown: ctl_EditComboDown.ShowDropDown(FALSE); ctl_EditComboDown.GetWindowText(strText); SetItemText(itemX,itemY,strText); ctl_EditComboDown.ShowWindow(SW_HIDE); break; case ctr_Edit_Text: ctl_EditText.GetWindowText(strText); SetItemText(itemX,itemY,strText); ctl_EditText.ShowWindow(SW_HIDE); break; case ctr_Edit_Time: strText=ctl_EditDateTime.GetDetectText(); SetItemText(itemX,itemY,strText); ctl_EditDateTime.ShowWindow(SW_HIDE); break; case ctr_Edit_Date: strText=ctl_EditDateTime.GetDetectText(); SetItemText(itemX,itemY,strText); ctl_EditDateTime.ShowWindow(SW_HIDE); case ctr_Edit_DateTime: strText=ctl_EditDateTime.GetDetectText(); SetItemText(itemX,itemY,strText); ctl_EditDateTime.ShowWindow(SW_HIDE); break; case ctr_Edit_Num: strText=ctl_EditNum.GetText(); SetItemText(itemX,itemY,strText); ctl_EditNum.ShowWindow(SW_HIDE); break; default: ctl_EditText.ShowWindow(SW_HIDE); ctl_EditDateTime.ShowWindow(SW_HIDE); ctl_EditComboDown.ShowWindow(SW_HIDE); ctl_EditNum.ShowWindow(SW_HIDE); break; } } //右键单击显示菜单 void CMyListCtrl::OnLButtonDblClk( UINT nFlags, CPoint point ) { if(itemY>=0) SetEditPos(FALSE,itemX,itemY,FALSE); if(m_EditStyle==ctr_Edit_DblClick) { int i=itemY; BOOL bln; if(itemY>=0) SetEditPos(FALSE,itemX,itemY,FALSE); GetItemPos(point); bln=(i==itemY); SetEditPos(TRUE,itemX,itemY,bln); } CListCtrl::OnLButtonDblClk(nFlags,point); } void CMyListCtrl::OnLButtonDown( UINT nFlags, CPoint point ) { if(itemY>=0) SetEditPos(FALSE,itemX,itemY,FALSE); if(m_EditStyle==ctr_Edit_Click) { int i=itemY; BOOL bln; if(itemY>=0) SetEditPos(FALSE,itemX,itemY,FALSE); GetItemPos(point); bln=(i==itemY); SetEditPos(TRUE,itemX,itemY,bln); } CListCtrl::OnLButtonDown(nFlags,point); } void CMyListCtrl::GetItemPos(CPoint point) { LVHITTESTINFO lvhti; lvhti.pt = point; int nItem = CListCtrl::SubItemHitTest(&lvhti); if(nItem == -1) return; int nSubItem = lvhti.iSubItem; itemX=nItem; itemY=nSubItem; } void CMyListCtrl::SetEditPos(BOOL blnShow,int itemX,int itemY,BOOL blnCbo) { if(!blnAllEdit) return; if(itemX<0||itemY<0) return; if(m_EditStyle==ctr_Edit_No) return; CString strText; int i; if(GetMyStyle()!=LVS_REPORT) return; if(!blnShow) { switch(GetColumnStyle(itemY)) { case ctr_Edit_CboDownList: ctl_EditComboDownList.ShowDropDown(FALSE); ctl_EditComboDownList.GetWindowText(strText); SetItemText(itemX,itemY,strText); ctl_EditComboDownList.ShowWindow(SW_HIDE); break; case ctr_Edit_CboDown: ctl_EditComboDown.ShowDropDown(FALSE); ctl_EditComboDown.GetWindowText(strText); SetItemText(itemX,itemY,strText); ctl_EditComboDown.ShowWindow(SW_HIDE); break; case ctr_Edit_Text: ctl_EditText.GetWindowText(strText); SetItemText(itemX,itemY,strText); ctl_EditText.ShowWindow(SW_HIDE); break; case ctr_Edit_Time: strText=ctl_EditDateTime.GetDetectText(); SetItemText(itemX,itemY,strText); ctl_EditDateTime.ShowWindow(SW_HIDE); break; case ctr_Edit_Date: strText=ctl_EditDateTime.GetDetectText(); SetItemText(itemX,itemY,strText); ctl_EditDateTime.ShowWindow(SW_HIDE); case ctr_Edit_DateTime: strText=ctl_EditDateTime.GetDetectText(); SetItemText(itemX,itemY,strText); ctl_EditDateTime.ShowWindow(SW_HIDE); break; case ctr_Edit_Num: strText=ctl_EditNum.GetText(); SetItemText(itemX,itemY,strText); ctl_EditNum.ShowWindow(SW_HIDE); break; default: ctl_EditText.ShowWindow(SW_HIDE); ctl_EditDateTime.ShowWindow(SW_HIDE); ctl_EditComboDown.ShowWindow(SW_HIDE); ctl_EditNum.ShowWindow(SW_HIDE); break; } //Invalidate(TRUE); return; } CRect rcCtrl; strText=GetItemText(itemX,itemY); CListCtrl::GetSubItemRect(itemX,itemY,LVIR_LABEL,rcCtrl); switch(GetColumnStyle(itemY)) { case ctr_Edit_CboDownList: if(!blnCbo) FillCboData(itemY); rcCtrl.bottom=rcCtrl.top+150; i=ctl_EditComboDownList.FindString(0,strText); if(i>=0) ctl_EditComboDownList.SetCurSel(i); else ctl_EditComboDownList.SetCurSel(0); ctl_EditComboDownList.MoveWindow(rcCtrl,TRUE); ctl_EditComboDownList.ShowWindow(SW_SHOW); ::SetFocus(ctl_EditComboDownList.m_hWnd); break; case ctr_Edit_CboDown: if(!blnCbo) FillCboData(itemY); rcCtrl.bottom=rcCtrl.top+150; i=ctl_EditComboDown.FindString(0,strText); if(i>=0) ctl_EditComboDown.SetCurSel(i); ctl_EditComboDown.SetWindowText(strText); ctl_EditComboDown.MoveWindow(rcCtrl,TRUE); ctl_EditComboDown.ShowWindow(SW_SHOW); ::SetFocus(ctl_EditComboDown.m_hWnd); break; case ctr_Edit_Date: ctl_EditDateTime.SetClassType(edit_date); ctl_EditDateTime.SetDetectText(strText); ctl_EditDateTime.MoveWindow(rcCtrl,TRUE); ctl_EditDateTime.ShowWindow(SW_SHOW); ::SetFocus(ctl_EditDateTime.m_hWnd); ctl_EditDateTime.SetSel(0,strText.GetLength(),TRUE); break; case ctr_Edit_DateTime: ctl_EditDateTime.SetClassType(edit_datetime); ctl_EditDateTime.SetDetectText(strText); ctl_EditDateTime.MoveWindow(rcCtrl,TRUE); ctl_EditDateTime.ShowWindow(SW_SHOW); ::SetFocus(ctl_EditDateTime.m_hWnd); ctl_EditDateTime.SetSel(0,strText.GetLength(),TRUE); break; case ctr_Edit_Time: ctl_EditDateTime.SetClassType(edit_time); ctl_EditDateTime.SetDetectText(strText); ctl_EditDateTime.MoveWindow(rcCtrl,TRUE); ctl_EditDateTime.ShowWindow(SW_SHOW); ::SetFocus(ctl_EditDateTime.m_hWnd); ctl_EditDateTime.SetSel(0,strText.GetLength(),TRUE); break; case ctr_Edit_Text: ctl_EditText.SetWindowText(strText); ctl_EditText.MoveWindow(rcCtrl,TRUE); ctl_EditText.ShowWindow(SW_SHOW); ::SetFocus(ctl_EditText.m_hWnd); ctl_EditText.SetSel(0,strText.GetLength(),TRUE); break; case ctr_Edit_Num: ctl_EditNum.blnAuto=GetNumEditAuto(itemY); ctl_EditNum.SetNumType(GetNumEditStyle(itemY)->x,GetNumEditStyle(itemY)->y); ctl_EditNum.SetText(strText); ctl_EditNum.MoveWindow(rcCtrl,TRUE); ctl_EditNum.ShowWindow(SW_SHOW); ::SetFocus(ctl_EditNum.m_hWnd); ctl_EditNum.SetSel(0,strText.GetLength(),TRUE); break; default: break; } } void CMyListCtrl::SetItemFont(CFont ft) { ctl_EditComboDown.SetFont(&ft,TRUE); ctl_EditText.SetFont(&ft,TRUE); ctl_EditDateTime.SetFont(&ft,TRUE); ctl_EditNum.SetFont(&ft,TRUE); ctl_EditComboDownList.SetFont(&ft,TRUE); } void CMyListCtrl::OnRButtonDown( UINT nFlags, CPoint point ) { if(!blnMenu) return; CMenu m_MyRightMenu; m_MyRightMenu.CreatePopupMenu(); m_MyRightMenu.AppendMenu(MF_STRING,ID_MENU_No,"无模式"); m_MyRightMenu.AppendMenu(MF_STRING,ID_MENU_Click,"单击模式"); m_MyRightMenu.AppendMenu(MF_STRING,ID_MENU_DblClick,"双击模式"); m_MyRightMenu.AppendMenu(MF_SEPARATOR,ID_MENU_sep,""); m_MyRightMenu.AppendMenu(MF_STRING,ID_MENU_icon,"大图标"); m_MyRightMenu.AppendMenu(MF_STRING,ID_MENU_smallicon,"小图标"); m_MyRightMenu.AppendMenu(MF_STRING,ID_MENU_list,"列表"); m_MyRightMenu.AppendMenu(MF_STRING,ID_MENU_report,"详细信息"); DWORD newStyle=GetMyStyle(); switch(newStyle) { case LVS_ICON: m_MyRightMenu.CheckMenuItem(ID_MENU_icon,MF_CHECKED); break; case LVS_SMALLICON: m_MyRightMenu.CheckMenuItem(ID_MENU_smallicon,MF_CHECKED); break; case LVS_LIST: m_MyRightMenu.CheckMenuItem(ID_MENU_list,MF_CHECKED); break; case LVS_REPORT: m_MyRightMenu.CheckMenuItem(ID_MENU_report,MF_CHECKED); break; default: break; } ClientToScreen(&point); m_MyRightMenu.TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,point.x,point.y,this,NULL); m_MyRightMenu.DestroyMenu(); CListCtrl::OnRButtonDown(nFlags,point); } //添加单列 int CMyListCtrl::InsertColumnX(CString strName,int nFormat,int iWidth,int intEdit) { int i; i=InsertColumn( m_iNumColumns++, strName, nFormat, iWidth ); if(i!=-1) { CString str; str.Format("%d",intEdit); strArrayEditStyle.InsertAt(i,str); if(intEdit==ctr_Edit_CboDown||intEdit==ctr_Edit_CboDownList) { CStringArray *strArray=new CStringArray; str.Format("%d",i); i=CboArrayIndex.GetSize(); CboArrayIndex.InsertAt(i,str); CboArrayData.InsertAt(i,strArray); } if(intEdit==ctr_Edit_Num) { str.Format("%d",i); i=NumArrayIndex.GetSize(); NumArrayIndex.InsertAt(i,str); CPoint *pt=new CPoint(10,0); NumArrayData.InsertAt(i,(CObject *)pt); str="0"; NumArrayAuto.InsertAt(i,str); } } return i; } void CMyListCtrl::AddCboItem(int nItem,CString strText) { CStringArray *strArray=GetCboArrayData(nItem); strArray->Add(strText); } void CMyListCtrl::RemoveCboItem(int nitem,CString strText) { CStringArray *strArray=GetCboArrayData(nitem); for(int i=0;i<strArray->GetSize();i++) { if(strArray->GetAt(i)==strText) { strArray->RemoveAt(i,strText.GetLength()); return; } } } void CMyListCtrl::SetNumEditAuto(int nitem,BOOL blnAuto) { if(GetColumnStyle(nitem)!=ctr_Edit_Num) return; CString str; str.Format("%d",nitem); int i=0; while(NumArrayIndex.GetAt(i)!=str && i<NumArrayIndex.GetSize()) { i=i+1; } if(i==NumArrayIndex.GetSize() && NumArrayIndex.GetAt(i)!=str) return; if(blnAuto) str="1"; else str="0"; NumArrayAuto.SetAt(i,str); } BOOL CMyListCtrl::GetNumEditAuto(int nitem) { if(GetColumnStyle(nitem)!=ctr_Edit_Num) return NULL; CString str; str.Format("%d",nitem); int i=0; while(NumArrayIndex.GetAt(i)!=str && i<NumArrayIndex.GetSize()) { i=i+1; } if(i==NumArrayIndex.GetSize() && NumArrayIndex.GetAt(i)!=str) return NULL; str=NumArrayAuto.GetAt(i); BOOL bln; if(str=="1") bln=TRUE; else bln=FALSE; return bln; } void CMyListCtrl::SetNumEditStyle(int nitem,int intLeft,int intRight) { CPoint *pt=GetNumEditStyle(nitem); pt->x=intLeft; pt->y=intRight; } CPoint *CMyListCtrl::GetNumEditStyle(int nitem) { CString str; str.Format("%d",nitem); int i=0; while(NumArrayIndex.GetAt(i)!=str && i<NumArrayIndex.GetSize()) { i=i+1; } if(i==NumArrayIndex.GetSize() && NumArrayIndex.GetAt(i)!=str) return NULL; CPoint *pt1=(CPoint *)NumArrayData.GetAt(i); return pt1; } void CMyListCtrl::FillCboData(int nitem) { //ctl_EditComboDown.DeleteString() if(GetColumnStyle(nitem)==ctr_Edit_CboDown) { ctl_EditComboDown.ShowDropDown(FALSE); ctl_EditComboDown.ResetContent(); CStringArray *strArry=GetCboArrayData(nitem); for(int i=0;i<strArry->GetSize();i++) { ctl_EditComboDown.AddString(strArry->GetAt(i)); } } if(GetColumnStyle(nitem)==ctr_Edit_CboDownList) { ctl_EditComboDownList.ShowDropDown(FALSE); ctl_EditComboDownList.ResetContent(); ctl_EditComboDownList.AddString(""); CStringArray *strArry=GetCboArrayData(nitem); for(int i=0;i<strArry->GetSize();i++) { ctl_EditComboDownList.AddString(strArry->GetAt(i)); } } } CStringArray *CMyListCtrl::GetCboArrayData(int nitem) { CString str; str.Format("%d",nitem); int i=0; while(CboArrayIndex.GetAt(i)!=str && i<CboArrayIndex.GetSize()) { i=i+1; } if(i==CboArrayIndex.GetSize() && CboArrayIndex.GetAt(i)!=str) return NULL; CStringArray *strArray=(CStringArray *)CboArrayData.GetAt(i); return strArray; } //设置单列 void CMyListCtrl::SetColumnStyle(int item,int intEdit) { CString str; str.Format("%d",intEdit); strArrayEditStyle.SetAt(item,str); } //得到单列 int CMyListCtrl::GetColumnStyle(int item) { CString str; str=strArrayEditStyle.GetAt(item); return(atoi(str)); } //设置列头 BOOL CMyListCtrl::SetHeader() { VERIFY( m_ctlHeader.SubclassWindow( GetHeaderCtrl()->GetSafeHwnd() ) ); m_ctlHeader.SetDefault(); return TRUE; } //释放内存 void CMyListCtrl::FreeItemMemory( const int iItem ) { ItemData* pid = reinterpret_cast<ItemData*>( CListCtrl::GetItemData( iItem ) ); LPTSTR* arrpsz = pid->arrpsz; for( int i = 0; i < m_iNumColumns; i++ ) delete[] arrpsz[ i ]; delete[] arrpsz; delete pid; VERIFY( CListCtrl::SetItemData( iItem, NULL ) ); } //删除单项 BOOL CMyListCtrl::DeleteItem( int iItem ) { FreeItemMemory( iItem ); return CListCtrl::DeleteItem( iItem ); } //删除单项 BOOL CMyListCtrl::DeleteAllItems() { for( int iItem = 0; iItem < GetItemCount(); iItem ++ ) FreeItemMemory( iItem ); return CListCtrl::DeleteAllItems(); } //数字型的判断 bool IsNumber( LPCTSTR pszText ) { ASSERT_VALID_STRING(pszText); int iDotCount=0; for(int i=0;i<lstrlen(pszText);i++){ if(!_istdigit(pszText[i])){ if(pszText[i]!='.') return false; iDotCount++; if(iDotCount>1)return false; } } return true; } //数字型的比较 int NumberCompare( LPCTSTR pszNumber1, LPCTSTR pszNumber2 ) { ASSERT_VALID_STRING(pszNumber1); ASSERT_VALID_STRING(pszNumber2); const double fNumber1=atof(pszNumber1); const double fNumber2=atof(pszNumber2); if(fNumber1<fNumber2) return -1; else if(fNumber1>fNumber2) return 1; return 0; } //时间性的判断 bool IsTime(LPCTSTR pszText) { ASSERT_VALID_STRING( pszText ); if( lstrlen( pszText ) != 8 ) return false; return _istdigit(pszText[0]) && _istdigit(pszText[1]) && pszText[2]==_T(':') && _istdigit( pszText[ 3 ] ) && _istdigit( pszText[ 4 ] ) && pszText[5]==_T(':') && _istdigit( pszText[ 6 ] ) && _istdigit( pszText[ 7 ] ); } //日期型的判断 bool IsDate( LPCTSTR pszText ) { ASSERT_VALID_STRING( pszText ); if( lstrlen( pszText ) != 10 ) return false; return _istdigit(pszText[0]) && _istdigit(pszText[1]) && pszText[2]==_T('-') && _istdigit( pszText[ 3 ] ) && _istdigit( pszText[ 4 ] ) && pszText[5]==_T('-') && _istdigit( pszText[ 6 ] ) && _istdigit( pszText[ 7 ] ) && _istdigit( pszText[ 8 ] ) && _istdigit( pszText[ 9 ] ); } //日期时间型的判断 bool IsDateTime(LPCTSTR pszText) { ASSERT_VALID_STRING( pszText ); if( lstrlen( pszText ) != 18 ) return false; return _istdigit(pszText[0]) && _istdigit(pszText[1]) && pszText[2]==_T(':') && _istdigit( pszText[ 3 ] ) && _istdigit( pszText[ 4 ] ) && pszText[5]==_T(':') && _istdigit( pszText[ 6 ] ) && _istdigit( pszText[ 7 ] ) && _istdigit(pszText[ 8 ]) && _istdigit(pszText[9]) && _istdigit(pszText[10]) && pszText[11]==_T('-') && _istdigit( pszText[ 12 ] ) && _istdigit( pszText[ 13] ) && pszText[14]==_T('-') && _istdigit( pszText[ 15 ] ) && _istdigit( pszText[ 16 ] ) && _istdigit( pszText[ 17 ] ) && _istdigit( pszText[ 18 ] ); } //日期和时间性的比较 int DateTimeComPare(const CString &strTime1,const CString &strTime2) { const int iHour1=atoi(strTime1.Mid(6, 2)); const int iHour2=atoi(strTime2.Mid(6, 2)); if(iHour1<iHour2) return -1; else if(iHour1>iHour2) return 1; const int iMin1=atoi(strTime1.Mid(3, 2)); const int iMin2=atoi(strTime2.Mid(3, 2)); if(iMin1<iMin2) return -1; else if(iMin1>iMin2) return 1; const int iSec1=atoi(strTime1.Mid(0, 2)); const int iSec2=atoi(strTime2.Mid(0, 2)); if(iSec1<iSec2) return -1; else if(iSec1>iSec2) return 1; const int iYear1=atoi(strTime1.Mid(15, 4)); const int iYear2=atoi(strTime2.Mid(15, 4)); if(iYear1<iYear2) return -1; else if(iYear1>iYear2) return 1; const int iMonth1=atoi(strTime1.Mid(12, 2)); const int iMonth2=atoi(strTime2.Mid(12, 2)); if(iMonth1<iMonth2) return -1; else if(iMonth1>iMonth2) return 1; const int iDay1=atoi(strTime1.Mid(9, 2)); const int iDay2=atoi(strTime2.Mid(9, 2)); if(iDay1<iDay2) return -1; else if(iDay1>iDay2) return 1; return 0; } //时间型的比较 int TimeCompare(const CString &strTime1,const CString &strTime2) { const int iHour1=atoi(strTime1.Mid(6, 2)); const int iHour2=atoi(strTime2.Mid(6, 2)); if(iHour1<iHour2) return -1; else if(iHour1>iHour2) return 1; const int iMin1=atoi(strTime1.Mid(3, 2)); const int iMin2=atoi(strTime2.Mid(3, 2)); if(iMin1<iMin2) return -1; else if(iMin1>iMin2) return 1; const int iSec1=atoi(strTime1.Mid(0, 2)); const int iSec2=atoi(strTime2.Mid(0, 2)); if(iSec1<iSec2) return -1; else if(iSec1>iSec2) return 1; return 0; } //日期型的比较 int DateCompare( const CString& strDate1, const CString& strDate2 ) { const int iYear1=atoi(strDate1.Mid(6, 4)); const int iYear2=atoi(strDate2.Mid(6, 4)); if(iYear1<iYear2) return -1; else if(iYear1>iYear2) return 1; const int iMonth1=atoi(strDate1.Mid(3, 2)); const int iMonth2=atoi(strDate2.Mid(3, 2)); if(iMonth1<iMonth2) return -1; else if(iMonth1>iMonth2) return 1; const int iDay1=atoi(strDate1.Mid(0, 2)); const int iDay2=atoi(strDate2.Mid(0, 2)); if(iDay1<iDay2) return -1; else if(iDay1>iDay2) return 1; return 0; } int CALLBACK CMyListCtrl::CompareFunction( LPARAM lParam1, LPARAM lParam2, LPARAM lParamData ) { CMyListCtrl* pListCtrl = reinterpret_cast<CMyListCtrl*>( lParamData ); ASSERT( pListCtrl->IsKindOf( RUNTIME_CLASS( CListCtrl ) ) ); ItemData* pid1 = reinterpret_cast<ItemData*>( lParam1 ); ItemData* pid2 = reinterpret_cast<ItemData*>( lParam2 ); ASSERT( pid1 ); ASSERT( pid2 ); LPCTSTR pszText1 = pid1->arrpsz[ pListCtrl->m_iSortColumn ]; LPCTSTR pszText2 = pid2->arrpsz[ pListCtrl->m_iSortColumn ]; ASSERT_VALID_STRING( pszText1 ); ASSERT_VALID_STRING( pszText2 ); if(IsNumber(pszText1)) return pListCtrl->m_bSortAscending ? NumberCompare( pszText1, pszText2 ) : NumberCompare( pszText2, pszText1 ); else if(IsDate(pszText1)) return pListCtrl->m_bSortAscending ? DateCompare( pszText1, pszText2 ) : DateCompare( pszText2, pszText1 ); else if(IsTime(pszText1)) return pListCtrl->m_bSortAscending ? TimeCompare( pszText1, pszText2 ) : TimeCompare( pszText2, pszText1 ); else if(IsDateTime(pszText1)) return pListCtrl->m_bSortAscending ? DateTimeComPare( pszText1, pszText2 ) : DateTimeComPare( pszText2, pszText1 ); else return pListCtrl->m_bSortAscending ? lstrcmp( pszText1, pszText2 ) : lstrcmp( pszText2, pszText1 ); } void CMyListCtrl::OnColumnClick( NMHDR* pNMHDR, LRESULT* pResult ) { SetEditPos(FALSE,itemX,itemY,FALSE); NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; const int iColumn = pNMListView->iSubItem; Sort( iColumn, iColumn == m_iSortColumn ? !m_bSortAscending : TRUE ); *pResult = 0; } void CMyListCtrl::Sort( int iColumn, BOOL bAscending ) { m_iSortColumn = iColumn; m_bSortAscending = bAscending; m_ctlHeader.SetSortArrow( m_iSortColumn, m_bSortAscending ); VERIFY( SortItems( CompareFunction, reinterpret_cast<DWORD>( this ) ) ); } void CMyListCtrl::OnDestroy() { for( int iItem = 0; iItem < GetItemCount(); iItem ++ ) FreeItemMemory( iItem ); CListCtrl::OnDestroy(); } BOOL CMyListCtrl::SetItemText( int nItem, int nSubItem, LPCTSTR lpszText ) { if( !CListCtrl::SetItemText( nItem, nSubItem, lpszText ) ) return FALSE; LPTSTR* arrpsz = GetTextArray( nItem ); LPTSTR pszText = arrpsz[ nSubItem ]; delete[] pszText; pszText = new TCHAR[ lstrlen( lpszText ) + 1 ]; (void)lstrcpy( pszText, lpszText ); arrpsz[ nSubItem ] = pszText; return TRUE; } BOOL CMyListCtrl::SetItemData( int nItem, DWORD dwData ) { if( nItem >= GetItemCount() ) return FALSE; ItemData* pid = reinterpret_cast<ItemData*>( CListCtrl::GetItemData( nItem ) ); ASSERT( pid ); pid->dwData = dwData; return TRUE; } DWORD CMyListCtrl::GetItemData( int nItem ) const { ASSERT( nItem < GetItemCount() ); ItemData* pid = reinterpret_cast<ItemData*>( CListCtrl::GetItemData( nItem ) ); ASSERT( pid ); return pid->dwData; } BOOL CMyListCtrl::SetTextArray( int iItem, LPTSTR* arrpsz ) { ASSERT( CListCtrl::GetItemData( iItem ) == NULL ); ItemData* pid = new ItemData; pid->arrpsz = arrpsz; return CListCtrl::SetItemData( iItem, reinterpret_cast<DWORD>( pid ) ); } LPTSTR* CMyListCtrl::GetTextArray( int iItem ) const { ASSERT( iItem < GetItemCount() ); ItemData* pid = reinterpret_cast<ItemData*>( CListCtrl::GetItemData( iItem ) ); return pid->arrpsz; } void CMyListCtrl::SetShowMenu(BOOL blnShow) { blnMenu=blnShow; } BOOL CMyListCtrl::PreTranslateMessage(MSG* pMsg) { int i=itemX,j=itemY; CRect rcCtrl; if(pMsg->message == WM_KEYDOWN) { if(pMsg->wParam == VK_TAB) { if((itemY+1)<=m_iNumColumns) { SetEditPos(FALSE,i,j,FALSE); if(FALSE == Key_Ctrl(i,j)) Key_Shift(i,j); CListCtrl::GetSubItemRect(i,j,LVIR_LABEL,rcCtrl); if(m_EditStyle==ctr_Edit_Click) OnLButtonDown(0,CPoint(rcCtrl.left+1,rcCtrl.top+1)); else OnLButtonDblClk(0,CPoint(rcCtrl.left+1,rcCtrl.top+1)); POSITION pos = CListCtrl::GetFirstSelectedItemPosition(); if (pos == NULL) { } else { while (pos) { int ntpItem = CListCtrl::GetNextSelectedItem(pos); CListCtrl::SetItemState(ntpItem,0,LVIS_SELECTED); } } CListCtrl::SetItemState(i, LVIS_SELECTED, LVIS_SELECTED); return TRUE; } } else if(pMsg->wParam == VK_RETURN) { short sRet = GetKeyState(VK_CONTROL); sRet = sRet >>15; if(sRet == 0) { if(GetColumnStyle(j)!=ctr_Edit_No) { SetEditPos(FALSE,i,j,FALSE); Key_Shift(i,j); CListCtrl::GetSubItemRect(i,j,LVIR_LABEL,rcCtrl); if(m_EditStyle==ctr_Edit_Click) OnLButtonDown(0,CPoint(rcCtrl.left+1,rcCtrl.top+1)); else OnLButtonDblClk(0,CPoint(rcCtrl.left+1,rcCtrl.top+1)); } return TRUE; } else { if(GetColumnStyle(j)==ctr_Edit_CboDown) ctl_EditComboDown.ShowDropDown(TRUE); if(GetColumnStyle(j)==ctr_Edit_CboDownList) ctl_EditComboDownList.ShowDropDown(TRUE); return TRUE; } } if(pMsg->wParam == VK_LEFT) { short sRet = GetKeyState(VK_CONTROL); sRet = sRet >>15; if(sRet!= 0) { switch(GetColumnStyle(j)) { case ctr_Edit_No: break; case ctr_Edit_Text: ctl_EditText.SetSel(0,0); break; case ctr_Edit_Date: ctl_EditDateTime.SetSel(0,0); break; case ctr_Edit_DateTime: ctl_EditDateTime.SetSel(0,0); break; case ctr_Edit_Time: ctl_EditDateTime.SetSel(0,0); break; case ctr_Edit_CboDown: ctl_EditComboDown.SetEditSel(0,0); break; // case ctr_Edit_CboDownList: // ctl_EditComboDownList.SetEditSel(0,0); // break; case ctr_Edit_Num: ctl_EditNum.SetSel(0,0); break; } return TRUE; } } if(pMsg->wParam == VK_RIGHT) { short sRet = GetKeyState(VK_CONTROL); sRet = sRet >>15; if(sRet!= 0) { switch(GetColumnStyle(j)) { case ctr_Edit_No: break; case ctr_Edit_Text: ctl_EditText.SetSel(-1); break; case ctr_Edit_Date: ctl_EditDateTime.SetSel(-1); break; case ctr_Edit_DateTime: ctl_EditDateTime.SetSel(-1); break; case ctr_Edit_Time: ctl_EditDateTime.SetSel(-1); break; case ctr_Edit_Num: ctl_EditNum.SetSel(-1); break; case ctr_Edit_CboDown: CString str; ctl_EditComboDown.GetWindowText(str); ctl_EditComboDown.SetEditSel(str.GetLength(),str.GetLength()); break; } return TRUE; } } if(pMsg->wParam == VK_DOWN) { CString strText; short sRet = GetKeyState(VK_CONTROL); sRet = sRet >>15; if(sRet!= 0) { switch(GetColumnStyle(j)) { case ctr_Edit_No: break; case ctr_Edit_Text: ctl_EditText.GetWindowText(strText); ctl_EditText.SetSel(0,strText.GetLength()); break; case ctr_Edit_Date: strText=ctl_EditDateTime.GetDetectText(); ctl_EditDateTime.SetSel(0,strText.GetLength()); break; case ctr_Edit_DateTime: strText=ctl_EditDateTime.GetDetectText(); ctl_EditDateTime.SetSel(0,strText.GetLength()); break; case ctr_Edit_Time: strText=ctl_EditDateTime.GetDetectText(); ctl_EditDateTime.SetSel(0,strText.GetLength()); break; case ctr_Edit_Num: strText=ctl_EditNum.GetText(); ctl_EditNum.SetSel(0,strText.GetLength()); break; case ctr_Edit_CboDown: if(ctl_EditComboDown.GetCount()>0) ctl_EditComboDown.SetCurSel(ctl_EditComboDown.GetCount()-1); break; case ctr_Edit_CboDownList: if(ctl_EditComboDownList.GetCount()>0) ctl_EditComboDownList.SetCurSel(ctl_EditComboDownList.GetCount()-1); break; default: break; } return TRUE; } } if(pMsg->wParam == VK_UP) { CString strText; short sRet = GetKeyState(VK_CONTROL); sRet = sRet >>15; if(sRet!= 0) { switch(GetColumnStyle(j)) { case ctr_Edit_No: break; case ctr_Edit_Text: ctl_EditText.GetWindowText(strText); ctl_EditText.SetSel(0,strText.GetLength()); break; case ctr_Edit_Date: strText=ctl_EditDateTime.GetDetectText(); ctl_EditDateTime.SetSel(0,strText.GetLength()); break; case ctr_Edit_DateTime: strText=ctl_EditDateTime.GetDetectText(); ctl_EditDateTime.SetSel(0,strText.GetLength()); break; case ctr_Edit_Time: strText=ctl_EditDateTime.GetDetectText(); ctl_EditDateTime.SetSel(0,strText.GetLength()); break; case ctr_Edit_Num: strText=ctl_EditNum.GetText(); ctl_EditNum.SetSel(0,strText.GetLength()); break; case ctr_Edit_CboDown: if(ctl_EditComboDown.GetCount()>0) ctl_EditComboDown.SetCurSel(0); break; case ctr_Edit_CboDownList: if(ctl_EditComboDownList.GetCount()>0) ctl_EditComboDownList.SetCurSel(0); break; default: break; } return TRUE; } } } return CListCtrl::PreTranslateMessage(pMsg); } void CMyListCtrl::OnParentNotify(UINT message, LPARAM lParam) { CListCtrl::OnParentNotify(message, lParam); ////////////////////////////////////////////////////////////////////////// CHeaderCtrl* pHeaderCtrl = CListCtrl::GetHeaderCtrl(); if(pHeaderCtrl == NULL) return; CRect rcHeader; pHeaderCtrl->GetWindowRect(rcHeader); ScreenToClient(rcHeader); //The x coordinate is in the low-order word and the y coordinate is in the high-order word. CPoint pt; pt.x = (int)LOWORD(lParam); pt.y = (int)HIWORD(lParam); if(rcHeader.PtInRect(pt) && message == WM_LBUTTONDOWN) { ctl_EditComboDown.ShowWindow(SW_HIDE); ctl_EditDateTime.ShowWindow(SW_HIDE); ctl_EditText.ShowWindow(SW_HIDE); ctl_EditNum.ShowWindow(SW_HIDE); } } BOOL CMyListCtrl::Key_Shift(int& nItem,int& nSub) { int nItemCount = CListCtrl::GetItemCount(); CHeaderCtrl* pHeader = CListCtrl::GetHeaderCtrl(); if(pHeader == NULL) return FALSE; short sRet = GetKeyState(VK_SHIFT); int nSubcCount = pHeader->GetItemCount(); sRet = sRet >>15; if(sRet == 0) { nSub += 1; if(nSub >= nSubcCount) { if(nItem == nItemCount-1) { nItem = 0; nSub = 0; } else { nSub = 0; nItem += 1; } } if(nItem >= nItemCount) nItem = nItemCount-1; return FALSE; } else { nSub -= 1; if(nSub < 0) { nSub = nSubcCount -1; nItem --; } if(nItem < 0) nItem = nItemCount-1; return TRUE; } return FALSE; } BOOL CMyListCtrl::Key_Ctrl(int& nItem,int &nSub) { short sRet = GetKeyState(VK_CONTROL); sRet = sRet >>15; int nItemCount = CListCtrl::GetItemCount(); if(sRet == 0) { } else { nItem = nItem >=nItemCount-1? 0:nItem+=1; return TRUE; } return FALSE; } void CMyListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { SetEditPos(FALSE,itemX,itemY,FALSE); CListCtrl::OnHScroll(nSBCode,nPos,pScrollBar); } void CMyListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { SetEditPos(FALSE,itemX,itemY,FALSE); CListCtrl::OnVScroll(nSBCode,nPos,pScrollBar); } void CMyListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { if (!lpDrawItemStruct) return; CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CRect rcItem; CFont ft; ft.CreateFont(10,10,0,0, FW_NORMAL,FALSE,FALSE,FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_MODERN, "MS Sans Serif"); GetSubItemRect(lpDrawItemStruct->itemID,0,LVIR_LABEL,rcItem); CString str; str.Format("%d-----%d",lpDrawItemStruct->itemID,0); pDC->SelectObject(&ft); pDC->SetTextColor(RGB(255,0,0)); pDC->TextOut(rcItem.left,rcItem.top,str); }